/* eslint-disable require-atomic-updates */
/** *
 * Created by Simple on 2018/1/14 0014.
 * Http请求控制器模块
 */

import http from 'axios'
import { Loading, Message } from 'element-ui'
import router from '@/router'
import conf from '@config'
import util from '@util'
import refreshToken from './refreshToken'
const instance = http.create()
// instance 配置
instance.defaults.timeout = 1000 * 30
instance.defaults.baseURL = process.env.NODE_ENV === 'production' ? conf.productionUrl : conf.devUrl
instance.setToken = (token) => {
  instance.defaults.headers.Authorization = token
  util.setCookie(conf.AUTHTOKEN_STORE_KEY, token) // jwt
}

// 配置通用请求动画
let loading = null
// 是否正在刷新的标记
let isRefreshing = false
// 重试队列，每一项将是一个待执行的函数形式
let requests = []

/**
  * 通用请求拦截配置
  * @param {*} config
  */
const instanceConf = (config) => {
  // ===========================签名 S=====================================
  const { noncestr, timestamp, sign } = util.getSign(config)
  config.headers.noncestr = noncestr
  config.headers.timestamp = timestamp
  config.headers.sign = sign
  // ===========================签名 E=====================================
  config.headers.platform = `PC`
  // ===========================移除重置空字符串 S=====================================
  util.resetParamsEmpty(config)
  // ===========================移除重置空字符串 E=====================================
  config.headers.Authorization = util.getCookie(conf.AUTHTOKEN_STORE_KEY)
  if (config.url.indexOf('/user/gqrcstatus') === -1) {
    loading = Loading.service({
      lock: true,
      text: '拼命加载中...',
      background: 'rgba(255, 255, 255, .8)'
    })
  }
  return config
}

instance.interceptors.request.use(instanceConf, err => {
  if (loading && err) loading.close()
  return Promise.reject(err)
})

// http response 拦截器
instance.interceptors.response.use(async(response) => {
  let data = {}
  if (response && response.data) {
    const code = Number(response.code || response.data.code)
    data = response.data
    if (code === 200) {
      data = response.data
    } else if (code === 402) {
      if (!isRefreshing) {
        isRefreshing = true
        try {
          const { data: { token }} = await refreshToken()
          if (token) {
            instance.setToken(token)
            response.config.headers.Authorization = token
            // 已经刷新了token，将所有队列中的请求进行重试
            requests.forEach(cb => cb(token))
            requests = []
            return instance(instanceConf(response.config))
          }
        } catch (error) { // 刷新时候直接判断token 不用判断code
          console.error('refreshtoken error =>', error)
          routerRedirect({ redirect: router.currentRoute.fullPath })
        } finally {
          isRefreshing = false
        }
      } else {
        // 正在刷新token，将返回一个未执行resolve的promise
        return new Promise((resolve) => {
          // 将resolve放进队列，用一个函数形式来保存，等token刷新后直接执行
          requests.push((token) => {
            response.config.headers.Authorization = token
            resolve(instance(instanceConf(response.config)))
          })
        })
      }
    } else if (code === 401) {
      routerRedirect({ redirect: router.currentRoute.fullPath })
    } else if (![30073, 30072, 30074, 30078, 30075, 30076].includes(code)) {
      Message.error(response.data && response.data.message || '网络连接出错!请稍后刷新重试!')
    }
  }
  if (loading) loading.close()
  return data
}, (error) => {
  console.log(`object`, error)
  if (loading) loading.close()
  Message.error('哎呀~ (ಥ﹏ಥ)网络又开小差了,请稍后刷新重试!')
  return Promise.reject(error.response.data)
})

/**
  * 重定向
  */
const routerRedirect = ({ path = '/login', redirect }) => {
  Message.warning(`身份过期，请重新登录!`)
  if (router.currentRoute.path !== '/login') {
    setTimeout(() => {
      router.replace({ path, query: { redirect }})
    }, 1200)
  }
}

export default instance
